package com.smart.manager.wiki.entities.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import com.smart.common.entities.constant.ArcoTips;
import com.smart.common.entities.constant.SocKetTips;
import com.smart.common.entities.core.Page;
import com.smart.manager.wiki.entities.body.RIntelRemind;
import com.smart.manager.wiki.entities.enums.NoticeScope;
import com.smart.manager.wiki.entities.enums.RemindChannel;
import com.smart.manager.wiki.entities.models.WikiIntelRemind;
import com.smart.manager.wiki.entities.models.query.QWikiIntelRemind;
import com.smart.service.socket.WebSocket;
import com.smart.wap.bodys.WinkBody;
import io.ebean.DB;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @author Administrator
 */
@Service
@Log4j2
@RequiredArgsConstructor
public class IntelRemindRepository {

    private WebSocket webSocket;


    public Page<WikiIntelRemind> pageList(RIntelRemind.SearchBody search) {

        QWikiIntelRemind query = new QWikiIntelRemind();
        Opt.ofBlankAble(search.getTitle()).ifPresent(x -> query.title.contains(x));
        query.order().id.desc();
        query.setFirstRow(search.firstRow()).setMaxRows(search.maxRows());
        return new Page<WikiIntelRemind>().load(query.findPagedList());
    }

    public void add(RIntelRemind.EditBody body) {
        BeanUtil.copyProperties(body, WikiIntelRemind.class)
                .setSendTime(LocalDateTime.now())
                .setChannel(RemindChannel.SITE)
                .setActionTime(LocalDateTime.now()).save();
    }


    public void update(Long id, RIntelRemind.EditBody body) {
        QWikiIntelRemind query = new QWikiIntelRemind();
        WikiIntelRemind record = query.id.eq(id).setMaxRows(1).findOne();
        Assert.notNull(record, "修改失败:提醒数据不存在或已被删除");
        BeanUtil.copyProperties(body, record);
        Objects.requireNonNull(record).update();
    }

    public int delByIds(List<Long> ids) {
        List<WikiIntelRemind> list = new QWikiIntelRemind().id.in(ids).findList();
        Assert.notEmpty(list, ArcoTips.DELETE_NOT_FOUND);
        return DB.deleteAll(list);
    }

    /**
     * @param scope       用户群体
     * @param recipientId 接收人ID
     * @param search      搜索条件
     * @return {@code Page<WikiIntelRemind>}
     */
    public Page<WikiIntelRemind> getPageList(NoticeScope scope, Long recipientId, WinkBody.RemindSearchBody search) {
        QWikiIntelRemind query = new QWikiIntelRemind().recipientId.eq(recipientId).scope.eq(scope).sendTime.isNotNull();
        if (search.getFilterRead()) {
            query.readTime.isNull();
        }
        query.order().id.desc();
        query.setFirstRow(search.firstRow()).setMaxRows(search.maxRows());
        return new Page<WikiIntelRemind>().load(query.findPagedList());
    }

    /**
     * 设置提醒消息单独已读
     *
     * @param scope       用户群体
     * @param recipientId 用户ID
     * @param id          消息ID
     * @return
     */
    public int changeToRead(NoticeScope scope, Long recipientId, Long id) {
        return new QWikiIntelRemind().recipientId.eq(recipientId).scope.eq(scope).sendTime.isNotNull().id.eq(id).deleted.isFalse()
                .asUpdate()
                .set(QWikiIntelRemind.Alias.readTime, LocalDateTime.now()).update();

    }

    /**
     * 一键设置消息移动
     *
     * @param scope       用户群体
     * @param recipientId 用户ID
     * @return 返回设置已读消息的条数
     */
    public int oneKeyToRead(NoticeScope scope, Long recipientId) {
        return new QWikiIntelRemind().recipientId.eq(recipientId).scope.eq(scope)
                .deleted.isFalse()
                .sendTime.isNotNull().readTime.isNull()
                .asUpdate()
                .set(QWikiIntelRemind.Alias.readTime, LocalDateTime.now()).update();
    }


    /**
     * 发送站内提醒
     *
     * @param scope       用户群体
     * @param recipientId 用户ID
     * @param title       提醒标题
     * @param content     提醒内容
     */
    public void sendSiteRemind(NoticeScope scope, Long recipientId, String title, String content) {
        LocalDateTime now = LocalDateTime.now();
        try {
            webSocket.sendOneMessage(recipientId,SocKetTips.systemNotice);
        }catch (Exception e){
            log.warn("发送Websocket消息失败"+e.getMessage());
        }

        new WikiIntelRemind().setChannel(RemindChannel.SITE).setScope(scope).setRecipientId(recipientId)
                .setTitle(title).setContent(content)
                .setSendTime(now).setActionTime(now)
                .save();
    }




}
